package com.ruoyi.common.core.dao;

import java.util.HashMap;
import java.util.Map;

import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.ValidateUtil;

/**
 * 1、参数话sql构造器，使用hql在并发查询存在解析的性能，因此并发量大的必须使用sql执行，而相应的sql应该禁止使用String想加和参数拼接
 * 2、使用StringBuilder来拼接sql字符串，是比String的+和StringBuferr性能都高 3、sql尽量使用参数化，使用?和
 * :变量都可，这样可以提高sql的查询命中率，减少数据库在解析sql的性能消耗
 * @author zhuangyh
 *
 */
public class ParamSqlBuilder {
    private StringBuilder builder = new StringBuilder();
    private Map<String, Object> paramMap = new HashMap<String, Object>();
    private String paramType;
    public final static String INDEXPARAM = "INDEX";
    public final static String NAMEPARAM = "NAME";

    public ParamSqlBuilder() {
        builder = new StringBuilder();
    }

    public ParamSqlBuilder(Object str) {
        builder = builder.append(str);
    }

    /**
     * 添加字符串
     * @param str 字符串
     * @return
     * @author Administrator
     */
    public ParamSqlBuilder append(Object str) {
        builder.append(str);
        return this;
    }

    /**
     * 设置sql里变量未？的变量，即索引变量
     * @param param 参数
     * @return
     */
    public ParamSqlBuilder setIndexParam(Object param) {
        if(ValidateUtil.isNull(paramType))
        {
            paramType = this.INDEXPARAM;
        }
        else
        {
            if(!paramType.equals(this.INDEXPARAM))
            {
                throw new BaseException("无效的SQL参数定义方式，尝试设置为索引参数，但是已经设置过命名参数");
            }
        }
        paramMap.put(String.valueOf(paramMap.size()), param);
        return this;
    }

    /**
     * 设置sql里变量未？的变量，即索引变量,一次性全部设置
     * @param params 参数数组
     * @return
     */
    public ParamSqlBuilder setIndexParams(Object[] params) {

        for (Object param : params) {
            setIndexParam(param);
        }
        return this;
    }

    /**
     * 设置sql变量为名字的变量，即命名变量
     * @param key 变量名
     * @param param 参数
     * @return
     */
    public ParamSqlBuilder setNameParam(String key, Object param) {
        if(ValidateUtil.isNull(paramType))
        {
            paramType = this.NAMEPARAM;
        }
        else
        {
            if(!paramType.equals(this.NAMEPARAM))
            {
                throw new BaseException("无效的SQL参数定义方式，尝试设置为命名参数，但是已经设置过索引参数");
            }
        }
        paramMap.put(key, param);
        return this;
    }

    /**
     * 取SQL语句
     */
    public String getSql() {
        return builder.toString();
    }

    /**
     * 获取参数map集合
     * @return
     */
    public Map getParamMap() {
        return paramMap;
    }

    public String getParamType()
    {
        return this.paramType;
    }

}

